package com.syyo.gulimall.product.service.impl;

import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.syyo.common.domain.ResultVo;
import com.syyo.common.enums.ResultEnum;
import com.syyo.common.exception.SysException;
import com.syyo.common.utils.MyJSONUtils;
import com.syyo.gulimall.product.domain.entity.SkuImagesEntity;
import com.syyo.gulimall.product.domain.entity.SkuInfoEntity;
import com.syyo.gulimall.product.domain.entity.SpuInfoDescEntity;
import com.syyo.gulimall.product.domain.req.SkuInfoReq;
import com.syyo.gulimall.product.domain.vo.SeckillInfoVo;
import com.syyo.gulimall.product.domain.vo.SkuItemSaleAttrVo;
import com.syyo.gulimall.product.domain.vo.SkuItemVo;
import com.syyo.gulimall.product.domain.vo.SpuItemAttrGroupVo;
import com.syyo.gulimall.product.feign.SeckillFeign;
import com.syyo.gulimall.product.mapper.SkuImagesMapper;
import com.syyo.gulimall.product.mapper.SkuInfoMapper;
import com.syyo.gulimall.product.mapper.SpuInfoDescMapper;
import com.syyo.gulimall.product.service.AttrGroupService;
import com.syyo.gulimall.product.service.SkuInfoService;
import com.syyo.gulimall.product.service.SkuSaleAttrValueService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;


/**
 * sku信息
 *
 * @author syyo
 * @email syyo@gmail.com
 * @date 2021-01-20 09:32:12
 */
@Service
public class SkuInfoServiceImpl extends ServiceImpl<SkuInfoMapper, SkuInfoEntity> implements SkuInfoService {

    @Autowired
    private SkuInfoMapper skuInfoMapper;

    @Autowired
    private SkuImagesMapper skuImagesMapper;

    @Autowired
    private SpuInfoDescMapper spuInfoDescMapper;

    @Autowired
    private AttrGroupService attrGroupService;

    @Autowired
    private SkuSaleAttrValueService attrValueService;

    @Autowired
    private ThreadPoolExecutor executor;

    @Autowired
    SeckillFeign seckillFeign;
    /**
     * 新增
     */
    @Override
    @Transactional
    public int add(SkuInfoReq req) {
        SkuInfoEntity entity = new SkuInfoEntity();
        // 添加创建时间和更新时间
        BeanUtils.copyProperties(req, entity);
        int insert = skuInfoMapper.insert(entity);
        if (insert != 1) {
            throw new SysException(ResultEnum.E_10001.getCode(), ResultEnum.E_10001.getMessage());
        }
        return insert;
    }

    /**
     * 删除
     */
    @Override
    @Transactional
    public int del(Integer id) {
        int insert = skuInfoMapper.deleteById(id);
        if (insert != 1) {
            throw new SysException(ResultEnum.E_10002.getCode(), ResultEnum.E_10002.getMessage());
        }
        return insert;
    }

    /**
     * 编辑
     */
    @Override
    @Transactional
    public int edit(SkuInfoReq req) {
        SkuInfoEntity entity = new SkuInfoEntity();
        // 添加更新时间
        BeanUtils.copyProperties(req, entity);
        int insert = skuInfoMapper.updateById(entity);
        if (insert != 1) {
            throw new SysException(ResultEnum.E_10003.getCode(), ResultEnum.E_10003.getMessage());
        }
        return insert;
    }

    /**
     * 详情
     */
    @Override
    public SkuInfoEntity findOne(Long id) {
        return skuInfoMapper.selectById(id);
    }

    /**
     * 列表
     */
    @Override
    public IPage<SkuInfoEntity> findAll(Integer pageNum, Integer pageSize, SkuInfoReq req) {

        Page<SkuInfoEntity> teacherPage = new Page<SkuInfoEntity>(pageNum, pageSize);
        QueryWrapper<SkuInfoEntity> wrapper = new QueryWrapper<>();
        if (req.getBrandId() != null) {
            wrapper.eq("brand_id", req.getBrandId());
        }

        if (req.getCatalogId() != null) {
            wrapper.eq("catalog_id", req.getCatalogId());
        }
        if (req.getPriceMin() != null && req.getPriceMin().compareTo(new BigDecimal(0)) == 1) {
            wrapper.ge("price", req.getPriceMin());
        }

        if (req.getPriceMax() != null && req.getPriceMax().compareTo(new BigDecimal(0)) == 1) {
            wrapper.le("price", req.getPriceMax());
        }

        return skuInfoMapper.selectPage(teacherPage, wrapper);
    }

    @Override
    public SkuItemVo item(Long skuId) throws ExecutionException, InterruptedException {
        SkuItemVo skuItemVo = new SkuItemVo();
        // 使用CompletableFuture线程编排  supplyAsync 异步有返回值
        CompletableFuture<SkuInfoEntity> infoFuture = CompletableFuture.supplyAsync(() -> {
            // 1. sku的基本信息
            SkuInfoEntity info = skuInfoMapper.selectById(skuId);
            skuItemVo.setInfo(info);
            return info;
        }, executor);
        // 3,4,5要等1任务完成才执行 thenAcceptAsync 可以获取到上一步的结果
        CompletableFuture<Void> saleFuture = infoFuture.thenAcceptAsync((res) -> {
            // 3. spu的销售属性组合
            List<SkuItemSaleAttrVo> saleAttrVos = attrValueService.getSaleAttrsBySpuId(res.getSpuId());
            skuItemVo.setSaleAttrs(saleAttrVos);
        }, executor);

        CompletableFuture<Void> descpFuture = infoFuture.thenAcceptAsync((res) -> {
            // 4. spu的介绍
            SpuInfoDescEntity spuInfoDescEntity = spuInfoDescMapper.selectById(res.getSpuId());
            skuItemVo.setDesp(spuInfoDescEntity);
        }, executor);


        CompletableFuture<Void> baseFuture = infoFuture.thenAcceptAsync((res) -> {
            // 5. spu的规格参数
            List<SpuItemAttrGroupVo> list = attrGroupService.getAttrGroupWithAttrsBySpuId(res.getSpuId(), res.getCatalogId());
            skuItemVo.setAttrGroups(list);
        }, executor);


        CompletableFuture<Void> imageFuture = CompletableFuture.runAsync(() -> {
            // 2. sku的图片信息
            List<SkuImagesEntity> imagess = skuImagesMapper.selectList(new QueryWrapper<SkuImagesEntity>().eq("sku_id", skuId));
            skuItemVo.setSkuImages(imagess);
        }, executor);


        //6.查询当前sku是否参与秒杀
        CompletableFuture<Void> seckillFuture = CompletableFuture.runAsync(() -> {
        ResultVo result = seckillFeign.getSkuSeckillInfo(skuId);
            if (result.getCode() == 20000) {
                SeckillInfoVo seckillInfoVo = MyJSONUtils.typeCast(new TypeReference<SeckillInfoVo>() {
                }, result.getData());
                skuItemVo.setSeckillInfo(seckillInfoVo);
            }
        }, executor);

        CompletableFuture.allOf(saleFuture, descpFuture, baseFuture, imageFuture,seckillFuture).get();
        return skuItemVo;
    }

    @Override
    public BigDecimal getPrice(Long skuId) {
        SkuInfoEntity skuInfoEntity = skuInfoMapper.selectById(skuId);
        return skuInfoEntity.getPrice();
    }
}